﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LGPeWJNM.BaseClasses
{
    /// <summary>
    /// Classe estática com extensões para classes genéricas da .NET Framework
    /// </summary>
    public static class Extensions
    {
        /// <summary>
        /// Determina o custo total de uma rota
        /// </summary>
        /// <param name="clientes">Rota de clientes a ser contabilizada as distâncias</param>
        /// <returns>O total das distâncias entre os clientes em ordem da lista encadeada</returns>
        public static double CustoTotal(this LinkedList<ICliente> clientes)
        {
            double custoTotal = 0;

            var cliente = clientes.First;
            while (cliente.Next != null)
            {
                custoTotal += cliente.Value.Coordenada % cliente.Next.Value.Coordenada;
                cliente = cliente.Next;
            }
            return custoTotal;
        }

        /// <summary>
        /// Determina o custo total de uma rota
        /// </summary>
        /// <param name="clientes">Rota de clientes a ser contabilizada as distâncias</param>
        /// <returns>O total das distâncias entre os clientes em ordem da lista encadeada</returns>
        public static double CustoTotal(this IEnumerable<ICliente> clientes)
        {
            double custoTotal = 0;

            var cliente2 = new LinkedList<ICliente>(clientes);

            var cliente = cliente2.First;
            while (cliente.Next != null)
            {
                custoTotal += cliente.Value.Coordenada % cliente.Next.Value.Coordenada;
                cliente = cliente.Next;
            }
            return custoTotal;
        }

        /// <summary>
        /// Determina o custo total de um conjunto de rotas
        /// </summary>
        /// <param name="rotas">Conjunto de rotas a serem contabilizadas</param>
        /// <returns>Custo total somando os custos de cada rota do conjunto</returns>
        public static double CustoTotal(this IEnumerable<LinkedList<ICliente>> rotas)
        {
            return rotas.Select(s => s.CustoTotal()).Sum();
        }

        /// <summary>
        /// Determina o custo total de um conjunto de rotas
        /// </summary>
        /// <param name="rotas">Conjunto de rotas a serem contabilizadas</param>
        /// <returns>Custo total somando os custos de cada rota do conjunto</returns>
        public static double CustoTotal(this IEnumerable<IEnumerable<ICliente>> rotas)
        {
            return rotas.Select(s => s.CustoTotal()).Sum();
        }
    }
}